#ifndef CTERRAIN_H
#define CTERRAIN_H

#include <iostream>
#include <fstream>
#include <vector>

#include "d3d9.h"
#include "d3dx9.h"

class CTerrain
{

	// Nested vertex structure
	struct TerrainVertex
	{
		float _x, _y, _z;
		float _u, _v;
		
		TerrainVertex() {}
		TerrainVertex(float x, float y, float z, float u, float v)
		{
			_x = x;
			_y = y;
			_z = z;
			_u = u;
			_v = v;
		}	
		static const DWORD FVF;
	};
	
	int											m_nNumVertsPerRow;
	int											m_nNumVertsPerColumn;
	int											m_nCellSpacing;
	int											m_nNumCellsPerRow;
	int         									m_nNumCellsPerColumn;
	int											m_nWidth;
	int 											m_nDepth;
	int											m_nNumVerticies;
	int											m_nNumTriangles;
	
	float       									m_fHeightScale;
	std::vector<int>						m_vHeightMap;
	IDirect3DDevice9*				m_pDevice;
	IDirect3DVertexBuffer9*		m_vb;
	IDirect3DIndexBuffer9*			m_ib;
	IDirect3DTexture9*				m_pTex;
	bool									m_bLava;
	
	bool ReadRawFile(char* szFileName);

public:
	// constructor
	CTerrain(IDirect3DDevice9* pDevice, char* szFileName, int nNumVertsPerRow,
	         int nNumVertsPerColumn, int nCellSpacing, float fHeightScale);
	         
	~CTerrain();
	
	bool ComputeVerticies(void);
	bool ComputeIndicies(void);
	bool LoadTexture(char* szFileName);
	bool Draw(D3DXMATRIX* world, bool drawTris);
	bool GenTexture(D3DXVECTOR3* directionToLight);
	bool LightTerrain(D3DXVECTOR3* directionToLight);
	float ComputeShade(int cellRow, int cellCol, D3DXVECTOR3* directionToLight);

	float Lerp(float a, float b, float t); 

	// Accessors
	int GetHeightMapEntry(int nRow, int nColumn) const;
	float GetHeight(float x, float z);

	// Mutators
	void SetHeightMapEntry(int nRow, int nColumn, int nValue);

	void ToggleTerrainType(void) { m_bLava = !m_bLava; }
};

#endif
